package nexus.base
{
	import flash.display.Graphics;
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	
	public class NXSprite extends Sprite
	{
		
		//-----------------------------------------------------------------------------------
		//
		// private vars
		//
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// protected vars
		//
		//-----------------------------------------------------------------------------------
		
		private var _viewHeight : Number = -1;
		private var _viewWidth : Number = -1;
		private var _paddingTop : Number = 0;
		private var _paddingRight : Number = 0;
		private var _paddingBottom : Number = 0;
		private var _paddingLeft : Number = 0;
		private var _padding : Array = [];
		private var _backGroundColor : Number = -1;
		private var _backGroundAlpha : Number = 1;
		private var _bgLayer : Shape;
		private var _borderLayer : Shape;
		
		
		private var _borderTopColor : Number = -1;
		private var _borderTopThickness : Number = 1;
		private var _borderTopAlpha : Number = 1;
		private var _borderRightColor : Number = -1;
		private var _borderRightThickness : Number = 1;
		private var _borderRightAlpha : Number = 1;
		private var _borderBottomColor : Number = -1;
		private var _borderBottomThickness : Number = 1;
		private var _borderBottomAlpha : Number = 1;
		private var _borderLeftColor : Number = -1;
		private var _borderLeftThickness : Number = 1;
		private var _borderLeftAlpha : Number = 1;
		
		//-----------------------------------------------------------------------------------
		//
		// public vars
		//
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// constructor
		//
		//-----------------------------------------------------------------------------------
		public function NXSprite()
		{
			super();
			
			_bgLayer = new Shape();
			addChildAt( _bgLayer, 0 );
			
			_borderLayer = new Shape();
			addChild( _borderLayer );
			
			this.addEventListener(Event.ADDED_TO_STAGE, onStage );
		}
			
		//-----------------------------------------------------------------------------------
		//
		// setter / getter 
		//
		//-----------------------------------------------------------------------------------
		
		public function get backGroundAlpha():Number
		{
			return _backGroundAlpha;
		}

		public function set backGroundAlpha(value:Number):void
		{
			_backGroundAlpha = value;
			
		}

		public function get backGroundColor():Number
		{
			return _backGroundColor;
		}

		public function set backGroundColor(value:Number):void
		{
			_backGroundColor = value;
		}

		public function get borderLeftAlpha():Number
		{
			return _borderLeftAlpha;
		}

		public function set borderLeftAlpha(value:Number):void
		{
			_borderLeftAlpha = value;
			
		}

		public function get borderBottomAlpha():Number
		{
			return _borderBottomAlpha;
		}

		public function set borderBottomAlpha(value:Number):void
		{
			_borderBottomAlpha = value;
			
		}

		public function get borderRightAlpha():Number
		{
			return _borderRightAlpha;
		}

		public function set borderRightAlpha(value:Number):void
		{
			_borderRightAlpha = value;
			
		}

		public function get borderTopAlpha():Number
		{
			return _borderTopAlpha;
		}

		public function set borderTopAlpha(value:Number):void
		{
			_borderTopAlpha = value;
			
		}

		public function get borderLeftThickness():Number
		{
			return _borderLeftThickness;
		}

		public function set borderLeftThickness(value:Number):void
		{
			_borderLeftThickness = value;
			
		}

		public function get borderLeftColor():Number
		{
			return _borderLeftColor;
		}

		public function set borderLeftColor(value:Number):void
		{
			_borderLeftColor = value;
			
		}

		public function get borderBottomThickness():Number
		{
			return _borderBottomThickness;
		}

		public function set borderBottomThickness(value:Number):void
		{
			_borderBottomThickness = value;
			
		}

		public function get borderBottomColor():Number
		{
			return _borderBottomColor;
		}

		public function set borderBottomColor(value:Number):void
		{
			_borderBottomColor = value;
			
		}

		public function get borderRightThickness():Number
		{
			return _borderRightThickness;
		}

		public function set borderRightThickness(value:Number):void
		{
			_borderRightThickness = value;
			
		}

		public function get borderRightColor():Number
		{
			return _borderRightColor;
		}

		public function set borderRightColor(value:Number):void
		{
			_borderRightColor = value;
			
		}

		public function get borderTopThickness():Number
		{
			return _borderTopThickness;
		}

		public function set borderTopThickness(value:Number):void
		{
			_borderTopThickness = value;
			
		}

		public function get borderTopColor():Number
		{
			return _borderTopColor;
		}

		public function set borderTopColor(value:Number):void
		{
			_borderTopColor = value;
			
		}

		public function get paddingTop():Number
		{
			return _paddingTop;
		}

		public function set paddingTop(value:Number):void
		{
			_paddingTop = value;
			this._padding[ 0 ] = value;
			
		}

		public function get paddingRight():Number
		{
			return _paddingRight;
		}

		public function set paddingRight(value:Number):void
		{
			_paddingRight = value;
			this._padding[ 1 ] = value;
			
		}

		public function get paddingBottom():Number
		{
			return _paddingBottom;
		}

		public function set paddingBottom(value:Number):void
		{
			_paddingBottom = value;
			this._padding[ 2 ] = value;
			
		}

		public function get paddingLeft():Number
		{
			return _paddingLeft;
		}

		public function set paddingLeft(value:Number):void
		{
			_paddingLeft = value;
			this._padding[ 3 ] = value;
			
		}

		public function get padding():Array
		{
			return _padding;
		}

		public function set padding(value:Array):void
		{
			_padding = value;
			_paddingTop = (_padding[ 0 ] != null ) ? _padding[ 0 ] : 0;
			_paddingRight = (_padding[ 1 ] != null ) ? _padding[ 1 ] : 0;
			_paddingBottom = (_padding[ 2 ] != null ) ? _padding[ 2 ] : 0;
			_paddingLeft = (_padding[ 3 ] != null ) ? _padding[ 3 ] : 0;
			
		}

 		public function get viewWidth():Number
		{
			if( _viewWidth == -1 )
			{
				var len:int = numChildren;
				var min : Number;
				var max : Number;
				
				if( len > 1 )
				{
					min = getChildAt( 0 ).x;
					max = getChildAt( 0 ).x + getChildAt( 0 ).width;
				}
				
				for (var i:int = 1; i < len; i++) 
				{
					min = Math.min( min, getChildAt( i ).x );
					max = Math.max( max, getChildAt( i ).x + getChildAt( i ).width );
				}
				
				return Math.max( max - min , 0 );
			}
			
			return _viewWidth;
		}
		
		public function set viewWidth(value:Number):void
		{
			_viewWidth = value;
			
		}
		
		public function get viewHeight():Number
		{
			if( _viewHeight == -1 )
			{
				var len:int = numChildren;
				var min : Number;
				var max : Number;
				
				if( len > 1 )
				{
					min = getChildAt( 0 ).y;
					max = getChildAt( 0 ).y + getChildAt( 0 ).height;
				}
				
				for (var i:int = 1; i < len; i++) 
				{
					min = Math.min( min, getChildAt( i ).y );
					max = Math.max( max, getChildAt( i ).y + getChildAt( i ).height );
				}
				
				return Math.max( max - min , 0 );
			}
			return _viewHeight;
		}
		
		public function set viewHeight(value:Number):void
		{
			_viewHeight = value;
		}
		
		public function setViewSize( __width : Number, __height : Number ):void
		{
			this.viewWidth = __width;
			this.viewHeight = __height;
			
		}

		public function setXY(__x:Number=0, __y:Number=0):void{
			this.x = __x;
			this.y = __y;
		}
		
		public function set borderRectThickness(value:Array):void
		{
			_borderTopThickness = (value[0] == null) ? 1 : value[0];
			_borderRightThickness = (value[1] == null) ? 1 : value[1]
			_borderBottomThickness = (value[2] == null) ? 1 : value[2]
			_borderLeftThickness = (value[3] == null) ? 1 : value[3]
		}
		
		public function set borderRectColor(value:Array):void{
			_borderTopColor = (value[0] == null) ? -1 : value[0];
			_borderRightColor = (value[1] == null) ? -1 : value[1];
			_borderBottomColor = (value[2] == null) ? -1 : value[2];
			_borderLeftColor = (value[3] == null) ? -1 : value[3];
		}
		
		public function set borderRectAlpha(value:Array):void{
			_borderTopAlpha = (value[0] == null) ? 1 : value[0];
			_borderRightAlpha = (value[1] == null) ? 1 : value[1];
			_borderBottomAlpha = (value[2] == null) ? 1 : value[2];
			_borderLeftAlpha = (value[3] == null) ? 1 : value[3];
		}
		
		public function set borderAllThickness(value:Number):void{
			_borderTopThickness = value;
			_borderRightThickness = value;
			_borderBottomThickness = value;
			_borderLeftThickness = value;
		}
		
		public function set borderAllColor(value:uint):void{
			_borderTopColor = value;
			_borderRightColor = value;
			_borderBottomColor = value;
			_borderLeftColor = value;
		}
		
		public function set borderAllAlpha(value:Number):void{
			_borderTopAlpha = value;
			_borderRightAlpha = value;
			_borderBottomAlpha = value;
			_borderLeftAlpha = value;
		}
		
		//-----------------------------------------------------------------------------------
		//
		// public 
		//
		//-----------------------------------------------------------------------------------

		/**
		 * 스테이지에 붙자마자 실행되는 메서드 
		 */		
		public function init():void
		{
			
		}
		
		/**
		 * apply 를 통하거나, stage Resize 이벤트 발생시 호출됨.
		 */		
		public function updateDisplayList():void
		{
			updateDefaultDisplayList();
		}
		
		/**
		 * applyDefault를 통해 호출됨.
		 */		
		public function updateDefaultDisplayList():void
		{
			var g : Graphics;
			if( _backGroundColor != -1 )
			{
				g = _bgLayer.graphics;
				g.clear();
				g.beginFill( _backGroundColor, _backGroundAlpha );
				g.drawRect( 0,0,viewWidth, viewHeight );
				g.endFill();
			}
			
			g = _borderLayer.graphics;
			g.clear();
			if( _borderTopColor != -1 )
			{
				g.lineStyle( _borderTopThickness, _borderTopColor, _borderTopAlpha );
				g.moveTo( 0,0 );
				g.lineTo( viewWidth,0 );
			}
			if( _borderRightColor != -1 )
			{
				g.lineStyle( _borderRightThickness, _borderRightColor, _borderRightAlpha );
				g.moveTo( viewWidth,0 );
				g.lineTo( viewWidth,viewHeight );
			}
			if( _borderBottomColor != -1 )
			{
				g.lineStyle( _borderBottomThickness, _borderBottomColor, _borderBottomAlpha );
				g.moveTo( viewWidth,viewHeight );
				g.lineTo( 0,viewHeight );
			}
			if( _borderLeftColor != -1 )
			{
				g.lineStyle( _borderLeftThickness, _borderLeftColor, _borderLeftAlpha );
				g.moveTo( 0,viewHeight );
				g.lineTo( 0,0 );
			}
			
			if( contains( _borderLayer ) ) setChildIndex( _borderLayer, numChildren-1 );
			if( contains( _bgLayer ) ) setChildIndex( _bgLayer, 0 ); 
		}
		
		
		/**
		 * Display Object 사이즈 및 포지션 등의 변경시에는<br />
		 * 반드시 apply 를 호출해야 화면 rendering 에 적용이 된다. 
		 */		
		public function apply():void
		{
			this.updateDisplayList();
		}
		
		/**
		 * NXSprite 에서만 적용되는 배경그리기용 updateDefaultDisplayList
		 */		
		public function applyDefault():void
		{
			updateDefaultDisplayList()
		}
		
		
		//-----------------------------------------------------------------------------------
		//
		// protected
		//
		//-----------------------------------------------------------------------------------
		
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// private
		//
		//-----------------------------------------------------------------------------------
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// event
		//
		//-----------------------------------------------------------------------------------
		
		
		protected function onStage(e:Event):void
		{
			e.currentTarget.removeEventListener( e.type, arguments.callee, !e.bubbles );
			
			init();
			
			stage.addEventListener(Event.RESIZE, onStageResize );
		}	
		
		protected function onStageResize(e:Event):void
		{
			this.updateDisplayList();
		}		
		
		
		
		//-----------------------------------------------------------------------------------
		//
		// destory
		//
		//-----------------------------------------------------------------------------------
		public function destory():void
		{
			
		}
	}
		
}